package org.visionlibrary.image.filters.thresholding;

import java.awt.Point;

import javax.media.jai.TiledImage;

import org.visionlibrary.image.model.WindowFilter;


/*
 * Bernsen recommends WIN_SIZE = 31 and CONTRAST_THRESHOLD = 15.
 *
 * 1) Bernsen J. (1986) "Dynamic Thresholding of Grey-Level Images" 
 * Proc. of the 8th Int. Conf. on Pattern Recognition, pp. 1251-1255
 * 2) Sezgin M. and Sankur B. (2004) "Survey over Image Thresholding 
 * Techniques and Quantitative Performance Evaluation" Journal of 
 * Electronic Imaging, 13(1): 146-165 
 * http://citeseer.ist.psu.edu/sezgin04survey.html
 */
public class SimpleBrensenThreshold extends WindowFilter {
	protected int width = 31; // prefered 31x31 :/
	protected int height = 31;
	protected double contrast_threshold = 15;

	protected int foreground = 155; // foreground pixel value (default 0)
	protected int background = 0; // background pixel value (default 255 for

	// 8bpc image)

	public SimpleBrensenThreshold() {
		this(31, 31, 15);
	}

	public SimpleBrensenThreshold(int width, int height,
			double contrast_threshold) {
		this.width = width;
		this.height = height;
		this.contrast_threshold = contrast_threshold;
	}

	public SimpleBrensenThreshold(int width, int height,
			double contrast_threshold, int foreground, int background) {
		this.width = width;
		this.height = height;
		this.contrast_threshold = contrast_threshold;
		this.foreground = foreground;
		this.background = background;
	}

	@Override
	protected int getNewPixelVal(TiledImage src, Point p, int channel) {
		int min_gray = Integer.MAX_VALUE, max_gray = 0; /*
														 * min and max gray
														 * values in a
														 * particular window
														 */
		double mid_gray = 0; /* mid range of gray values in a particular window */
		int local_contrast = 0; /* contrast in a particular window */

		Point pIter = new Point();
		for (pIter.y = 0; pIter.y < windowHeight; pIter.y++)
			for (pIter.x = 0; pIter.x < windowWidth; pIter.x++) {
				int val = getWindowPixelVal(src, pIter, channel);
				if (val < min_gray) {
					min_gray = val;
				}
				if (max_gray < val) {
					max_gray = val;
				}

			}

		local_contrast = max_gray - min_gray;
		mid_gray = 0.5 * (min_gray + max_gray);

		if(local_contrast < contrast_threshold) {
			return ((mid_gray >= background/2) ? foreground
					: background);
		} else {
			return ((getWindowPixelVal(src, dstPointInWindow, channel) >= mid_gray) ? foreground
					: background);
		}
	}

	@Override
	protected void setWindowProperties() {
		windowWidth = width;
		windowHeight = height;
		dstPointInWindow = new Point(width / 2, height / 2);
	}
}
